home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / prsr_lib / soc_clnt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-30  |  8.6 KB  |  357 lines

  1. /*****************************************************************************
  2. *   Sockets routines to handle socket io of objects.                 *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, June 1993.  *
  5. *****************************************************************************/
  6.  
  7. #include <stdio.h>
  8. #include <sys/types.h>
  9.  
  10. #ifdef __UNIX__
  11. #if (defined(ultrix) && defined(mips)) || defined(_AIX) || defined(sgi)
  12. #    include <fcntl.h>
  13. #else
  14. #    include <sys/fcntl.h>
  15. #endif /* (ultrix && mips) || _AIX || sgi */
  16. #if defined(__hpux)
  17. #    include <sys/file.h>
  18. #endif /* __hpux */
  19. #include <sys/socket.h>
  20. #include <netinet/in.h>
  21. #include <netdb.h>
  22. #include <errno.h>
  23. #endif /* __UNIX__ */
  24.  
  25. #ifdef OS2GCC
  26. #    include <os2.h>
  27. HFILE IritPipe;
  28. #endif /* OS2GCC */
  29.  
  30. #ifdef __WINNT__
  31. #include <stdlib.h>
  32. #include <windows.h>
  33. #include <winsock.h>
  34. #include <io.h>
  35. #endif /* __WINNT__ */
  36.  
  37. #include "irit_sm.h"
  38. #include "irit_soc.h"
  39.  
  40. /* #define DEBUG_ECHO */
  41.  
  42. static char
  43.     GlblClientUnReadChar = 0;
  44.  
  45. static int
  46.     GlblBinaryIPC = FALSE,
  47.     GlblEchoInput = FALSE,
  48.     GlblCommuSoc = 0;
  49.  
  50. static void SocketPrintError(char *Str);
  51. static int SocReadObjPrefix(void);
  52.  
  53. /*****************************************************************************
  54. *  IO error print routine.                             *
  55. *****************************************************************************/
  56. static void SocketPrintError(char *Str)
  57. {
  58. #   if defined(__UNIX__) || defined(OS2GCC)
  59.     perror(Str);
  60. #   endif /* __UNIX__ || OS2GCC */
  61. #   ifdef __WINNT__
  62.     fprintf(stderr, "iritserver: %s error %d\n", Str, WSAGetLastError());
  63. #   endif /* __WINNT__ */
  64. }
  65.  
  66. /*****************************************************************************
  67. *  Set echo printing of read input.                         *
  68. *****************************************************************************/
  69. void SocClientEchoInput(int EchoInput)
  70. {
  71.     GlblEchoInput = EchoInput;
  72. }
  73.  
  74. /*****************************************************************************
  75. *  Non blocking read of a single char. Returns EOF if no data is found.         *
  76. *****************************************************************************/
  77. int SocClientReadCharNonBlock(void)
  78. {
  79.     int c;
  80.     static unsigned char Buffer[LINE_LEN_LONG];
  81.     static int
  82.     BufferSize = 0,
  83.     BufferPtr = 0;    
  84.  
  85.     if (GlblClientUnReadChar != 0) {
  86.     c = GlblClientUnReadChar;
  87.     GlblClientUnReadChar = 0;
  88.     return c;
  89.     }
  90.     else if (BufferPtr < BufferSize) {
  91.     c = Buffer[BufferPtr++];
  92.     return c;
  93.     }
  94.  
  95. #ifdef OS2GCC
  96.     DosRead(IritPipe, Buffer, LINE_LEN_LONG, (PULONG) &BufferSize);
  97. #endif /* OS2GCC */
  98. #if defined(__UNIX__) || defined(__WINNT__)
  99.     BufferSize = recv(GlblCommuSoc, Buffer, LINE_LEN_LONG, 0);
  100. #endif /* __UNIX__ || __WINNT__ */
  101.  
  102.     if (BufferSize > 0) {
  103.     if (GlblEchoInput) {
  104.         int i;
  105.         unsigned char
  106.         *p = Buffer;
  107.  
  108.         if (GlblBinaryIPC) {
  109.         for (i = 0; i < BufferSize; i++) {
  110.             if (i % 16 == 0)
  111.             printf("\n%04x: ", i);
  112.             printf("%02x ", *p++);
  113.         }
  114.         printf("\n");
  115.         }
  116.         else
  117.         for (i = 0; i < BufferSize; i++)
  118.             putc(*p++, stdout);
  119.     }
  120.     BufferPtr = 0;
  121.     c = Buffer[BufferPtr++];
  122.     }
  123.     else
  124.     c = EOF;
  125.  
  126.     return c;
  127. }
  128.  
  129. /*****************************************************************************
  130. *  Unget one char from client socket.                         *
  131. *****************************************************************************/
  132. void SocClientUnReadChar(char c)
  133. {
  134.     GlblClientUnReadChar = c;
  135. }
  136.  
  137. /*****************************************************************************
  138. * Get a single line for syncronization purposes that will prefix an object.  *
  139. *   Returns TRUE if prefix found, FALSE otherwise.                 *
  140. *****************************************************************************/
  141. static int SocReadObjPrefix(void)
  142. {
  143.     if (GlblBinaryIPC) {
  144.     int c;
  145.  
  146.     if ((c = SocClientReadCharNonBlock()) != EOF) {
  147.         SocClientUnReadChar(c);
  148.         return TRUE;
  149.     }
  150.     }
  151.     else {
  152.     if (SocClientReadCharNonBlock() == '[') {
  153.         SocClientUnReadChar('[');
  154.         return TRUE;
  155.     }
  156.     }
  157.  
  158.     return FALSE;
  159. }
  160.  
  161. /*****************************************************************************
  162. *  Non blocking read of a single line. Returns NULL if no line is available. *
  163. *****************************************************************************/
  164. char *SocClientReadLineNonBlock(void)
  165. {
  166.     static char Line[LINE_LEN_LONG];
  167.     static int
  168.     LineLen = 0;
  169.  
  170.     while (TRUE) {
  171.     int c;
  172.  
  173.     if ((c = SocClientReadCharNonBlock()) != EOF) {
  174.         if (c == '\n' || c == '\r') {
  175.         Line[LineLen++] = c;
  176.         Line[LineLen] = 0;
  177.  
  178.         LineLen = 0;
  179.         return Line;
  180.         }
  181.         else if (LineLen >= LINE_LEN_LONG - 1) {
  182.         IritPrsrFatalError("Socket read line too long\n");
  183.         exit(1);
  184.         }
  185.         else {
  186.         Line[LineLen++] = c;
  187.         }
  188.     }
  189.     else
  190.         return NULL;
  191.     }
  192. }
  193.  
  194. /*****************************************************************************
  195. *  Creates a client socket. Returns TRUE if succesful.                 *
  196. *****************************************************************************/
  197. int SocClientCreateSocket(void)
  198. {
  199. #if defined(__UNIX__) || defined(__WINNT__)
  200.     int s;
  201.     char *hostname, *portnum, hostnamestr[LINE_LEN];
  202.     struct sockaddr_in sain;
  203.     struct hostent *host;
  204.     struct servent *serv;
  205.  
  206.     GlblCommuSoc = 0;
  207.  
  208. #ifdef __WINNT__
  209.     {
  210.     WSADATA WSAData;
  211.  
  212.     if ((s = WSAStartup(MAKEWORD(1, 1), &WSAData)) != 0) {
  213.          fprintf(stderr, "iritserver: WSAStartup: error %d\n",
  214.              WSAGetLastError());
  215.          exit(1);
  216.     }
  217.     }
  218. #endif
  219.  
  220.     /* Get port address. */
  221.     gethostname(hostnamestr, LINE_LEN);
  222.     if ((hostname = getenv("IRIT_SERVER_HOST")) == NULL)
  223.     hostname = hostnamestr;
  224.  
  225.     if ((host = gethostbyname(hostname)) == NULL) {
  226.     SocketPrintError("iritclient: hostname unknown\n");
  227.     return FALSE;
  228.     }
  229.  
  230.     ZAP_MEM(&sain, sizeof(struct sockaddr_in));
  231.     GEN_COPY(&sain.sin_addr, host -> h_addr_list[0], host -> h_length);
  232.     sain.sin_family = AF_INET;
  233.  
  234.     if ((portnum = getenv("IRIT_SERVER_PORT")) != NULL)
  235.     sain.sin_port = atoi(portnum);
  236.     else if ((serv = getservbyname(IRIT_TCP_SERVICE, "tcp")) == NULL)
  237.     sain.sin_port = htons(IRIT_TCP_PORT);
  238.     else
  239.     sain.sin_port = serv->s_port;
  240.  
  241.     /* Create the socket, make it nonblocking and connect. */
  242.     if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  243.     SocketPrintError("iritclient: socket");
  244.     return FALSE;
  245.     }
  246.  
  247. #ifdef __UNIX__
  248. #ifdef __hpux
  249.     if (fcntl(s, F_SETFL, O_NDELAY) < 0) {
  250. #else
  251.     if (fcntl(s, F_SETFL, FNDELAY) < 0) {
  252. #endif /* __hpux */
  253.     SocketPrintError("iritclient: fcntl");
  254.     return FALSE;
  255.     }
  256. #endif /* __UNIX__ */
  257.  
  258.     while (connect(s, (struct sockaddr *) &sain,
  259.            sizeof(struct sockaddr_in)) < 0) {
  260. #    ifdef __UNIX__
  261.         if (errno == EINPROGRESS)
  262.         break;
  263. #    endif /* __UNIX__ */
  264. #    ifdef __WINNT__
  265.         if (WSAGetLastError() == WSAEINPROGRESS)
  266.         break;
  267. #    endif /* __WINNT__ */
  268.     SocketPrintError("iritclient: connect");
  269.     return FALSE;
  270.     }
  271.  
  272.     GlblCommuSoc = s;
  273. #endif /* __UNIX__ || __WINNT__ */
  274.  
  275. #ifdef OS2GCC
  276.     ULONG rc,
  277.     ulActionTaken, ulFileSize, ulFileAttribute, ulOpenFlag, ulOpenMode;
  278.     
  279.     DosWaitNPipe(IRIT_PIPE, NP_WAIT);
  280.     ulFileSize = 0;
  281.     ulFileAttribute = 0;
  282.     ulOpenFlag = OPEN_ACTION_OPEN_IF_EXISTS;
  283.     ulOpenMode = OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE;
  284.     rc = DosOpen(IRIT_PIPE,
  285.          &IritPipe,
  286.          &ulActionTaken,
  287.          ulFileSize,
  288.          ulFileAttribute,
  289.          ulOpenFlag,
  290.          ulOpenMode,
  291.          NULL);
  292.  
  293.     if (rc != 0) {
  294.         DosBeep(1000, 100);
  295.         exit(1);
  296.     }
  297.  
  298.     GlblCommuSoc = 1;
  299. #endif /* OS2GCC */
  300.  
  301.     GlblBinaryIPC = getenv("IRIT_BIN_IPC") != NULL;
  302.  
  303.     return TRUE;
  304. }
  305.  
  306. /*****************************************************************************
  307. *  Close a client socket.                             *
  308. *****************************************************************************/
  309. void SocClientCloseSocket(void)
  310. {
  311.     if (GlblCommuSoc > 0) {
  312. #ifdef __UNIX__
  313.     if (close(GlblCommuSoc) != 0)
  314.         SocketPrintError("iritclient: close");
  315. #endif /* __UNIX__ */
  316. #ifdef __WINNT__
  317.     closesocket(GlblCommuSoc);
  318. #endif /* __WINNT__ */
  319. #ifdef OS2GCC
  320.     DosClose(IritPipe);
  321. #endif /* OS2GCC */
  322.  
  323.     GlblCommuSoc = 0;
  324.     }
  325. }
  326.  
  327. /*****************************************************************************
  328. * Attempt to read (non blocking) from socket an object.                 *
  329. * If read is successful the object is returned, otherwise NULL is returned.  *
  330. *****************************************************************************/
  331. IPObjectStruct *SocClientReadOneObject(void)
  332. {
  333.     char *ErrorMsg;
  334.     IPObjectStruct *PObj;
  335.  
  336.     if (GlblCommuSoc > 0 && SocReadObjPrefix()) {
  337.     IritPrsrSetReadOneObject(TRUE);
  338.  
  339.     IritPrsrReadSocket(TRUE);
  340.     if (GlblBinaryIPC) {
  341.         PObj = IritPrsrGetBinObject(NULL);
  342.     }
  343.     else {
  344.         PObj = IritPrsrGetObjects(NULL);
  345.     }
  346.     IritPrsrReadSocket(FALSE);
  347.     }
  348.     else
  349.     PObj = NULL;
  350.  
  351.     if (IritPrsrParseError(&ErrorMsg)) {
  352.     fprintf(stderr, "Socket: %s\n", ErrorMsg);
  353.     }
  354.  
  355.     return PObj;
  356. }
  357.